package pruebas;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

import junit.framework.TestCase;
import juego.AvionCivil;
import juego.Avioneta;
import juego.Bombardero;
import juego.Botin;
import juego.Caza;
import juego.Cohete;
import juego.Coordenada;
import juego.Energia;
import juego.Explorador;
import juego.Impacto;
import juego.Laser;
import juego.Movil;


public class TestCaza extends TestCase {

	public void testMovimiento(){
		
		Caza caza = new Caza(0,0);
		
		ArrayList<Movil> listaDeMoviles = new ArrayList<Movil>();
		ArrayList<Botin> listaDeBotines = new ArrayList<Botin>();
		listaDeMoviles.add(caza);
		
		caza.vivir(listaDeMoviles,listaDeBotines);
		
		assertEquals (0, caza.verUbicacion().obtenerCoordenadaX());
		assertEquals (3, caza.verUbicacion().obtenerCoordenadaY());
		
	};
	
	public void testImpactoProvocado(){
		
		Movil movil = new Caza(0,8);
		Energia energia = new Energia(30);
		Impacto impacto = movil.impactoProvocado();
		impacto.herir(energia);
		assertEquals(20, energia.verEnergia());
		
	};
	
	public void testColision(){
	
		ArrayList<Movil> listaDeMoviles = new ArrayList<Movil>();
		ArrayList<Botin> listaDeBotines = new ArrayList<Botin>();
		
		Coordenada ubicacion = new Coordenada(0,0);
		Caza caza = new Caza(ubicacion);
	
		Coordenada ubicacionLaser = new Coordenada(0,9);
		Laser laser = new Laser(ubicacionLaser);
		
		Coordenada ubicacionLaser2 = new Coordenada(0,16);
		Laser laser2 = new Laser(ubicacionLaser2);
		
		laser.hacerLeal();
		laser2.hacerLeal();
		
		listaDeMoviles.add(caza);
		listaDeMoviles.add(laser);
		listaDeMoviles.add(laser2);
		
		int puntaje = caza.vivir(listaDeMoviles,listaDeBotines);
		assertTrue(listaDeMoviles.contains(caza));
		assertFalse(listaDeMoviles.contains(laser));
		assertTrue(puntaje == 0);

		caza.vivir(listaDeMoviles,listaDeBotines);
		puntaje = caza.vivir(listaDeMoviles,listaDeBotines);
			 
		assertFalse(listaDeMoviles.contains(caza));
		assertFalse(listaDeMoviles.contains(laser2));
		assertTrue(puntaje == 30);
		
	};
	
	public void testProvocarHuida(){

		ArrayList<Movil> listaDeMoviles = new ArrayList<Movil>();
		ArrayList<Botin> listaDeBotines = new ArrayList<Botin>();
		
		Coordenada ubicacion = new Coordenada(0,0);
		Caza caza = new Caza(ubicacion);
		caza.designarGuia();

		Coordenada ubicacionLaser = new Coordenada(0,2);
		Laser laser = new Laser(ubicacionLaser);
		Coordenada ubicacionCohete = new Coordenada(0,-2);
		Cohete cohete = new Cohete(ubicacionCohete);
		laser.hacerLeal();
		cohete.hacerLeal();
		Coordenada ubicacionCohete2 = new Coordenada(1,4);
		Cohete cohete2 = new Cohete(ubicacionCohete2);
		cohete2.hacerLeal();
		
		Coordenada ubicacionExplorador = new Coordenada(50,50);
		Explorador explorador = new Explorador(ubicacionExplorador);
		Coordenada ubicacionCaza2 = new Coordenada(40,50);
		Caza caza2 = new Caza(ubicacionCaza2);
		Coordenada ubicacionAvioneta = new Coordenada(30,50);
		Avioneta avioneta = new Avioneta(ubicacionAvioneta);
		Coordenada ubicacionBombardero = new Coordenada(20,50);
		Bombardero bombardero = new Bombardero(ubicacionBombardero);
		AvionCivil avionCivil = new AvionCivil(-100,-100);
		Coordenada ubicacionLaser2 = new Coordenada(100,100);
		Laser laser2 = new Laser(ubicacionLaser2);
		laser.hacerLeal();
		Coordenada ubicacionLaser3 = new Coordenada(10,50);
		Laser laser3 = new Laser(ubicacionLaser3);
		
		listaDeMoviles.add(avionCivil);
		listaDeMoviles.add(explorador);
		listaDeMoviles.add(avioneta);
		listaDeMoviles.add(laser);
		listaDeMoviles.add(caza);
		listaDeMoviles.add(bombardero);
		listaDeMoviles.add(laser3);
		listaDeMoviles.add(laser2);
		listaDeMoviles.add(caza2);
		listaDeMoviles.add(cohete2);
		
		//destruccion
		caza.vivir(listaDeMoviles,listaDeBotines);
		assertFalse(caza.estaVivo());
		assertFalse(listaDeMoviles.contains(caza));
		assertFalse(listaDeMoviles.contains(laser));
		assertFalse(listaDeMoviles.contains(cohete));
	    assertFalse(listaDeMoviles.contains(cohete2));
		
		//huida
		//siguen igual
		avionCivil.vivir(listaDeMoviles,listaDeBotines);
		assertEquals (-100, avionCivil.verUbicacion().obtenerCoordenadaX());
		assertEquals (-95, avionCivil.verUbicacion().obtenerCoordenadaY());
		laser2.vivir(listaDeMoviles, listaDeBotines);
		assertEquals (100, laser2.verUbicacion().obtenerCoordenadaX());
		assertEquals (110, laser2.verUbicacion().obtenerCoordenadaY());
		laser3.vivir(listaDeMoviles, listaDeBotines);
		assertEquals (10, laser3.verUbicacion().obtenerCoordenadaX());
		assertEquals (60, laser3.verUbicacion().obtenerCoordenadaY());
		
		//huyen
		explorador.vivir(listaDeMoviles,listaDeBotines);
		assertEquals (50, explorador.verUbicacion().obtenerCoordenadaX());
		assertEquals (40, explorador.verUbicacion().obtenerCoordenadaY());
		caza2.vivir(listaDeMoviles,listaDeBotines);
		assertEquals (40, caza2.verUbicacion().obtenerCoordenadaX());
		assertEquals (47, caza2.verUbicacion().obtenerCoordenadaY());
		avioneta.vivir(listaDeMoviles,listaDeBotines);
		assertEquals (30, avioneta.verUbicacion().obtenerCoordenadaX());
		assertEquals (35, avioneta.verUbicacion().obtenerCoordenadaY());
		bombardero.vivir(listaDeMoviles,listaDeBotines);
		assertEquals (20, bombardero.verUbicacion().obtenerCoordenadaX());
		assertEquals (45, bombardero.verUbicacion().obtenerCoordenadaY());
			
	};
	
	public void testDejarBotin(){
		
		ArrayList<Movil> listaDeMoviles = new ArrayList<Movil>();
		ArrayList<Botin> listaDeBotines = new ArrayList<Botin>();
		
		Coordenada ubicacion = new Coordenada(0,0);
		Caza caza = new Caza(ubicacion);
		assertEquals(0, listaDeBotines.size());
		
		Coordenada ubicacionLaser = new Coordenada(0,9);
		Laser laser = new Laser(ubicacionLaser);
		Coordenada ubicacionCohete = new Coordenada(0,18);
		Cohete cohete = new Cohete(ubicacionCohete);
		laser.hacerLeal();
		cohete.hacerLeal();
		Coordenada ubicacionCohete2 = new Coordenada(0,-16);
		Cohete cohete2 = new Cohete(ubicacionCohete2);
		cohete2.hacerLeal();
		
		listaDeMoviles.add(laser);
		listaDeMoviles.add(caza);
		listaDeMoviles.add(cohete);
		listaDeMoviles.add(cohete2);
		
		caza.vivir(listaDeMoviles,listaDeBotines);
		assertTrue(listaDeMoviles.contains(caza));
		assertFalse(listaDeMoviles.contains(laser));
		
		caza.vivir(listaDeMoviles, listaDeBotines);
		
		//destruccion
		caza.vivir(listaDeMoviles, listaDeBotines);
		assertFalse(caza.estaVivo());
		assertEquals(1, listaDeBotines.size());
	}
	
	public void testFueraDelEscenario(){
		ArrayList<Movil> listaDeMoviles = new ArrayList<Movil>();
		ArrayList<Botin> listaDeBotines = new ArrayList<Botin>();
		
		Caza avion = new Caza(404,464);
		listaDeMoviles.add(avion);
		
		assertTrue((listaDeMoviles.size() == 1));
		assertTrue(avion.estaVivo());
		
		for (int i = 1; i < 4; i++){
			avion.vivir(listaDeMoviles,listaDeBotines);
		}
		
		assertTrue((listaDeMoviles.size() == 0));
		assertFalse(avion.estaVivo());
	}
	
	private static void persistir(String archivo, Caza nave) {
		try {

			Document doc = DocumentBuilderFactory.newInstance()
					.newDocumentBuilder().newDocument();

			Element element = nave.getElement(doc);
			doc.appendChild(element);

			Transformer transformer = TransformerFactory.newInstance()
					.newTransformer();
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			transformer.transform(new DOMSource(doc), new StreamResult(
					new PrintStream(archivo)));

		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (TransformerConfigurationException e) {
			e.printStackTrace();
		} catch (TransformerFactoryConfigurationError e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (TransformerException e) {
			e.printStackTrace();
		}
	}

	private static Caza recuperar(String archivo) {
		try {
		
			Document doc = DocumentBuilderFactory.newInstance()
					.newDocumentBuilder().parse(new File(archivo));
			Element element = doc.getDocumentElement();

			Caza nave = Caza.fromElement(element);
			return nave;
		
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		}
	
		return null;
	}



	public void testPersistencia() {

		String archivo = "caza_java.xml";
		Caza naveOriginal = new Caza(5,40);
		assertTrue(naveOriginal.estaVivo());
		persistir(archivo, naveOriginal);
		Caza naveRecuperada = recuperar(archivo);
		assertEquals(5,naveRecuperada.getX());
		assertEquals(40,naveRecuperada.getY());
		assertFalse(naveRecuperada.verLealtad());
		assertTrue(naveRecuperada.estaVivo());
		ArrayList<Movil> lista = new ArrayList<Movil>();
		
		naveOriginal.vivir(new ArrayList<Movil>(),new ArrayList<Botin>());
		naveRecuperada.vivir(lista,new ArrayList<Botin>());
		assertEquals(naveOriginal.getX(),naveRecuperada.getX());
		assertEquals(naveOriginal.getY(),naveRecuperada.getY());
		assertEquals(1,lista.size());
		System.out.println(naveOriginal.getClass());
		
	}
	

}
